package jeconbond.experiment;

import laboratoryQ.experiment.IExperiment;
import laboratoryQ.experiment.IExperimentResult;
import laboratoryQ.experiment.settings.IExperimentSettings;
import jeconbond.experiment.generate.IAgentsCreator;
import jeconbond.experiment.generate.IEngineInitialiser;
import jeconbond.experiment.process.IJEBExperimentContext;
import jeconbond.experiment.generate.IAutomataGenerator;
import jeconbond.automata.INode;
import jeconbond.economic.IEconomicEngine;
import jeconbond.economic.EconomicEngine;
import jeconbond.economic.agent.IEconomicProducer;

public class JEBExperimentFlow implements IExperiment {
	public IAutomataGenerator automataGenerator;
	public IAgentsCreator agentCreator;
	public IEngineInitialiser engineInitialiser;

	@Override
	public IExperimentResult runExperiment(
			IExperimentSettings isettings,
			IExpRunStatusHandler expRunStatusHandler
	) {
		BaseJEBExperimentSettings settings = (BaseJEBExperimentSettings) isettings;
		IJEBExperimentContext experimentContext =
				(IJEBExperimentContext) settings.getExperimentContextFactory().newContext(settings);
		INode[] automatas = automataGenerator.generate(experimentContext);
		IEconomicProducer[] agents = agentCreator.automata2agents(automatas, experimentContext);
		IEconomicEngine engine = new EconomicEngine();
		engineInitialiser.initialise(engine, agents, experimentContext);
		int stepCount = settings.stepCount;
		for (int step = 0; step < stepCount; step++) {
			engine.processSteps(
					settings.stepSize,
					experimentContext.getRRS()
					);
			expRunStatusHandler.stepsProcessed(step + 1, stepCount);
		}
		expRunStatusHandler.handleExperimentResult(experimentContext);
		return experimentContext;
	}
}
